package com.blog.service.impl;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.extension.api.R;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.blog.domain.DTO.AddUserDto;
 import com.blog.domain.DTO.UserDto;
 import com.blog.domain.DTO.UserInfoDto;
 import com.blog.domain.DTO.UserStatusDto;
 import com.blog.domain.ResponseResult;
 import com.blog.domain.entity.Role;
 import com.blog.domain.entity.User;
 import com.blog.domain.entity.UserRole;
 import com.blog.domain.vo.PageVo;
 import com.blog.domain.vo.UserDetailInfoVo;
 import com.blog.domain.vo.UserDetailVo;
 import com.blog.domain.vo.UserInfoVo;
 import com.blog.enums.AppHttpCodeEnum;
 import com.blog.exception.SystemException;
 import com.blog.mapper.UserMapper;
 import com.blog.mapper.UserRoleMapper;
 import com.blog.service.RoleService;
 import com.blog.service.UserRoleService;
 import com.blog.service.UserService;
 import com.blog.utils.BeanCopyUtils;
 import com.blog.utils.SecurityUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.crypto.password.PasswordEncoder;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.StringUtils;

 import java.util.List;
 import java.util.Objects;
 import java.util.stream.Collectors;

/**
 * 用户表(User)表服务实现类
 *
 * @author makejava
 * @since 2024-09-08 18:55:57
 */
 @Service("userService")
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

	 @Autowired
	 private PasswordEncoder passwordEncoder;

	 @Autowired
	 private UserRoleMapper userRoleMapper;

	 @Autowired
	 private UserRoleService userRoleService;

	 @Autowired
	 private RoleService roleService;
	 @Override
	 public ResponseResult userInfo() {

		 //获取当前用户id
		 Long userId = SecurityUtils.getUserId();
		 //根据用户id 查询用户信息
		 User user = getById(userId);
		 //封装成userInfoVo返回
		 UserInfoVo vo = BeanCopyUtils.copyBean(user,UserInfoVo.class);
		 return ResponseResult.okResult(vo);
	 }

	 /**修改个人信息
	  *
	  * @param user
	  * @return
	  */
	 @Override
	 public ResponseResult updateUserInfo(User user) {
		 updateById(user);

		 return ResponseResult.okResult();

	 }

	 /**注册
	  *
	  * @param user
	  * @return
	  */
	 @Override
	 public ResponseResult register(User user) {
		 //对数据进行非空判断
		 if (!StringUtils.hasText(user.getUserName())){
			 throw new SystemException(AppHttpCodeEnum.USERNAME_NOT_NULL);
		 }
		 if (!StringUtils.hasText(user.getPassword())){
			 throw new SystemException(AppHttpCodeEnum.PASSWORD_NOT_NULL);
		 }
		 if (!StringUtils.hasText(user.getNickName())){
			 throw new SystemException(AppHttpCodeEnum.NICKNAME_NOT_NULL);
		 }
		 if (!StringUtils.hasText(user.getEmail())){
			 throw new SystemException(AppHttpCodeEnum.EMAIL_NOT_NULL);
		 }
		 //对数据进行是否存在的判断
		 if (UserNameExist(user.getUserName())){
			 throw new SystemException(AppHttpCodeEnum.USERNAME_EXIST);
		 }
		 if (NickNameExist(user.getNickName())){
			 throw new SystemException(AppHttpCodeEnum.NICKNAME_EXIST);
		 }
		 if (EmailExist(user.getEmail())){
			 throw new SystemException(AppHttpCodeEnum.EMAIL_EXIST);
		 }
		 //对密码进行加密
		 String encodepassword = passwordEncoder.encode(user.getPassword());
		 user.setPassword(encodepassword);
		 //存入数据库
		 save(user);
		 return ResponseResult.okResult();
	 }

	/**角色分页查询
	 *
	 * @param pageNum
	 * @param pageSize
	 * @param userDto
	 */
	@Override
	public ResponseResult getUserList(Integer pageNum, Integer pageSize, UserDto userDto) {
		//分页条件
		Page<User> page = new Page<>();
		page.setCurrent(pageNum);
		page.setSize(pageSize);
		//查询条件
		LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
		wrapper.eq(StringUtils.hasText(userDto.getStatus()),
				User::getStatus,userDto.getStatus());

		wrapper.like(StringUtils.hasText(userDto.getUserName()),
				User::getUserName,userDto.getUserName());

		wrapper.like(StringUtils.hasText(userDto.getPhonenumber()),
				User::getPhonenumber,userDto.getPhonenumber());

		//分页
		page(page,wrapper);

		//查询分页数据
		long total = page.getTotal();

		List<User> records = page.getRecords();


		//封装返回
		PageVo pageVo = PageVo.builder()
				.total(total)
				.rows(records)
				.build();

		return ResponseResult.okResult(pageVo);

	}

	/**新增用户
	 *
	 * @param addUserDto
	 * @return
	 */
	@Override
	public ResponseResult addUser(AddUserDto addUserDto) {
		//判断条件
		//对数据进行非空判断
		if (!StringUtils.hasText(addUserDto.getUserName())){
			throw new SystemException(AppHttpCodeEnum.USERNAME_NOT_NULL);
		}
		if (!StringUtils.hasText(addUserDto.getPassword())){
			throw new SystemException(AppHttpCodeEnum.PASSWORD_NOT_NULL);
		}
		//对数据进行是否存在的判断
		if (UserNameExist(addUserDto.getUserName())){
			throw new SystemException(AppHttpCodeEnum.USERNAME_EXIST);
		}
		if (EmailExist(addUserDto.getEmail())){
			throw new SystemException(AppHttpCodeEnum.EMAIL_EXIST);
		}
		if (PhoneNumberExist(addUserDto.getPhonenumber())){
			throw new SystemException(AppHttpCodeEnum.PHONENUMBER_EXIST);
		}
		if (NickNameExist(addUserDto.getNickName())){
			throw new SystemException(AppHttpCodeEnum.NICKNAME_EXIST);
		}
		//对密码进行加密
		String encodepassword = passwordEncoder.encode(addUserDto.getPassword());
		addUserDto.setPassword(encodepassword);
		//把基础数据插入user表中
		User user = BeanCopyUtils.copyBean(addUserDto, User.class);
		save(user);
		//把用户和角色的对应关系插入用户角色关联表中
		List<Long> roleIds = addUserDto.getRoleIds();
		List<UserRole> userRoles = roleIds.stream()
				.map(roleId -> new UserRole(user.getId(), roleId))
				.collect(Collectors.toList());
		userRoleService.saveBatch(userRoles);
		return ResponseResult.okResult();
	}

	/**删除用户
	 *
	 * @param ids
	 * @return
	 */
	@Override
	public ResponseResult deleteUser(List<Long> ids) {

		removeByIds(ids);
		return ResponseResult.okResult();


	}

	/** 根据id查询用户信息回显
	 *
	 * @param id
	 * @return
	 */
	@Override
	public ResponseResult getUserDetail(Long id) {
		//查询用户信息
		User user = getById(id);
		UserDetailInfoVo userDetailInfoVo
				= BeanCopyUtils.copyBean(user, UserDetailInfoVo.class);
		//查询所有角色集合
		List<Role> roles = roleService.list();
		//查询用户关联的角色id列表
		List<Long> roleIds = userRoleMapper.getUserRoleIds(id);
		//封装Vo返回
		UserDetailVo userDetailVo = new UserDetailVo(roleIds, roles, userDetailInfoVo);
		return ResponseResult.okResult(userDetailVo);
	}

	/**管理端更新用户信息
	 *
	 * @param userInfoDto
	 * @return
	 */
	@Override
	@Transactional
	public ResponseResult adminUpdateUserInfos(UserInfoDto userInfoDto) {
		//更新基础信息
		User user = BeanCopyUtils.copyBean(userInfoDto, User.class);
		updateById(user);
		//删除用户角色表中对应的信息
		LambdaQueryWrapper<UserRole> wrapper = new LambdaQueryWrapper<>();
		wrapper.eq(UserRole::getUserId,userInfoDto.getId());
		userRoleService.remove(wrapper);
		//重新插入
		List<Long> roleIds = userInfoDto.getRoleIds();
		List<UserRole> userRoles = roleIds.stream()
				.map(roleId -> new UserRole(userInfoDto.getId(), roleId))
				.collect(Collectors.toList());
		userRoleService.saveBatch(userRoles);
		//返回数据
		return ResponseResult.okResult();


	}

	/**更改用户状态
	 *
	 * @param  userStatusDto
	 * @return
	 */
	@Override
	public ResponseResult changeStatus(UserStatusDto userStatusDto) {
		User user = new User();
		user.setId(userStatusDto.getUserId());
		user.setStatus(userStatusDto.getStatus());
		user.setUpdateBy(SecurityUtils.getUserId());
		updateById(user);
		return ResponseResult.okResult();
	}

	private boolean EmailExist(String email) {
		LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper();
		queryWrapper.eq(User::getEmail,email);
		int count = count(queryWrapper);
		return count>0;
	}

	private boolean NickNameExist(String nickName) {
		LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper();
		queryWrapper.eq(User::getNickName,nickName);
		int count = count(queryWrapper);
		return count>0;
	}

	private boolean UserNameExist(String userName) {
		LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper();
		queryWrapper.eq(User::getUserName,userName);
		int count = count(queryWrapper);
		return count>0;
	}

	private boolean PhoneNumberExist(String phoneNumber){
		LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper();
		queryWrapper.eq(User::getPhonenumber,phoneNumber);
		int count = count(queryWrapper);
		return count>0;
	}
}
